﻿using Define;
using DotNetDetour;
using LogicCenter.Logic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Tools.Base;

namespace AssemblyPatch
{
    public class Patch
    {
        public int OnInit(GameClient player, string param1, string param2)
        {
            MyConsole.WriteLineEx(string.Format("Patch OnInit p1={0} p2={1} value={2}", param1, param2, player.GetName()), ConsoleColor.Green);
            return 0;
        }

        public int OnLine(GameClient player, string param1, string param2)
        {
            MyConsole.WriteLineEx(string.Format("Patch OnLine p1={0} p2={1} value={2}", param1, param2, player.GetName()), ConsoleColor.Green);
            return 0;
        }

        bool install_by_DotNetDetour = false;
        /// <summary>
        /// 使用DotNetDetour方式进行Hook
        /// </summary>
        /// <param name="param1"></param>
        /// <param name="param2"></param>
        /// <returns></returns>
        public int Once_ByDotNetDetour(string param1, string param2)
        {
            if (install_by_DotNetDetour)
                return 0;
            install_by_DotNetDetour = true;

            try
            {
                GameClient client = new GameClient()
                {
                    strName = "测试人员A",
                    nRoleID = 999,
                };

                MyConsole.WriteLineEx(string.Format("原先的人员名字：{0}", client.GetName()));
                DotNetDetour.Monitor.Install();
                MyConsole.WriteLineEx(string.Format("Hook之后的人员名字：{0}", client.GetName()));
            }
            catch(Exception ex)
            {
                LogManager.WriteLog(string.Format("{0} call Once_ByDotNetDetour Failed. ExceptionMsg={1}.", this.ToString(), ex.Message), ex);
            }

            return 0;
        }

        bool install_by_HotFix = false;
        public int Once_ByHotFix(string param1, string param2)
        {
            if (install_by_HotFix)
                return 0;
            install_by_HotFix = true;

            try
            {


                NeedFixClass t = new NeedFixClass();
                MyConsole.WriteLineEx(string.Format("OldValue = {0}", t.GetValue()), ConsoleColor.Green);

                {
                    Type rawType = typeof(NeedFixClass);
                    MethodInfo rawMethodInfo = rawType.GetMethod("GetValue");

                    Type hookType = typeof(HookClass);
                    MethodInfo hookMethodInfo = hookType.GetMethod("GetMyValue");

                    int nRes = HotFixUtil.Fix(rawMethodInfo, hookMethodInfo, PactchSelect.Method1);
                    if (nRes != HotFixErrCode.Sucess)
                        nRes = HotFixUtil.Fix(rawMethodInfo, hookMethodInfo, PactchSelect.Method2);
                }

                t = new NeedFixClass();
                MyConsole.WriteLineEx(string.Format("CurValue = {0}", t.GetValue()), ConsoleColor.Green);
            }
            catch(Exception ex)
            {
                LogManager.WriteLog(string.Format("{0} Failed. ExceptionMsg={1}.", this.ToString(), ex.Message), ex);
            }
            return 0;
        }
    }

    /// <summary>
    /// 以下是使用DotNetDetour进行Hook的标准用法，此类将在DotNetDetour.Monitor.Install()时执行Hook。
    /// </summary>
    public class Custom_GameClient_GetName : IMethodMonitor //自定义一个类并继承IMethodMonitor接口
    {
        [Monitor("LogicCenter.Logic", "GameClient")] //你要hook的目标方法的名称空间，类名
        public string GetName() //方法签名要与目标方法一致
        {
            object o = this;
            if (o is GameClient)
            {
                GameClient client = (o as GameClient);
                string strRet = string.Format("{0}（感染后）", client.strName);
                return strRet;
            }

            return "nothing.";
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        [Original] //原函数标记
        public string Ori() //方法签名要与目标方法一致，命名随意。
        {
            return null; //这里写什么无所谓，能编译过即可
        }
    }
}
